<template>
  <div id="wave_form" :style="contentStyle">
    <div ref="graphics" id="graphics"></div>
    <!-- {{ dataInfo }} -->
  </div>
</template>

<script setup lang="tsx">
import { CSSProperties, computed, nextTick, onMounted, ref, watch } from 'vue';
import * as echarts from 'echarts';
import 'echarts/theme/macarons';
import { cloneDeep } from 'lodash-es';

let chart;
const graphics = ref();
const props = defineProps({
  height: {
    type: [String, Number],
    default: '100%',
  },
  stationType: {
    type: Array,
    default: ['EIZ', 'EIN', 'EIE'],
  },
  info: {
    type: Object,
    default: () => {},
  },
  dataInfo: {
    type: Object,
    default: () => {},
  },
  // 设置自定义grid
  grid: {
    type: Object,
    default: undefined,
  },
  showXAxis: {
    type: Boolean,
    default: true,
  },
  showTitle: {
    type: Boolean,
    default: true,
  },
});
const contentStyle = computed<CSSProperties>(() => {
  return {
    height: typeof height === 'number' ? height + 'px' : height,
    overflowY: 'auto',
  };
});

watch(
  () => props.dataInfo,
  (val) => {
    console.time('chart render time');
    renderChart(val);
    console.timeEnd('chart render time');
  },
);
const { height, stationType, info } = props;
const color = ['#77E3F9', '#F16995', '#DFC428'];

// 每60S更新一次
let date = new Date().getTime();
const wsData = ref({});
const channelData = ref({});
const channelDataOld = ref({});
//初始化图表
const init = () => {
  if (chart) chart.clear();
  chart = echarts.init(graphics.value);
  const line = {
    axisLabel: {
      color: '#fff',
    },
    splitLine: {
      show: false,
    },
    axisTick: {
      show: false,
    },
    axisLine: {
      show: false,
    },
  };
  const xAxis = stationType.map((channel, index) => {
    return {
      ...line,
      gridIndex: index,
      type: 'time',
      min: date + 1000,
      max: date + 1000 * 60,
      show: props.showXAxis,
    };
  });
  const yAxis = stationType.map((channel, index) => {
    return {
      ...line,
      gridIndex: index,
      type: 'value',
      splitLine: {
        lineStyle: {
          color: 'rgba(255, 255, 255, .12)',
          type: 'dashed',
        },
      },
      scale: true,
      name: props.showTitle ? '单位: 度(°)' : '',
      nameTextStyle: {
        color: '#fff',
      },
    };
  });

  const defaultGrid = stationType.map((channel, index) => {
    const length = stationType.length;
    return {
      show: true,
      top: `${(100 / length) * index + 10}%`,
      left: '7%',
      right: '3%',
      height: `${100 / length - 13}%`,
    };
  });
  const grid = props.grid ? props.grid : defaultGrid;
  console.log('init');
  console.log();

  chart.setOption({
    animation: false,
    color,
    title: {
      text: props.showTitle ? info.code : '',
      left: 'center',
      textStyle: {
        color: '#fff',
      },
    },
    tooltip: {
      trigger: 'axis',
    },
    axisPointer: {
      link: [
        {
          xAxisIndex: 'all',
        },
      ],
    },
    grid,
    xAxis,
    yAxis,
    series: [],
  });
  for (let key of stationType as string[]) {
    channelData.value[key] = [];
    channelDataOld.value[key] = [];
  }
};
onMounted(() => {
  init();
});

const renderChart = (e) => {
  for (let i in e) {
    if (wsData.value[i]) {
      wsData.value[i] = wsData.value[i].concat(e[i]);
    } else {
      wsData.value[i] = e[i];
    }
  }

  const series = [];
  const seriesOld = [];
  const now = new Date().getTime();
  let xAxis = {};

  //这里触发 走完一次波形
  if (now >= date + 1000 * 60) {
    //重新记录时间
    date = now;
    xAxis = {
      xAxis: stationType.map((channel, index) => {
        return {
          gridIndex: index,
          min: date + 1000,
          max: date + 1000 * 60,
        };
      }),
    };
    //存储上一次波形数据
    for (const channel of stationType as string[]) {
      const list = cloneDeep(wsData.value[channel]);
      channelDataOld.value[channel] = list.map((item) => {
        return [item[0] + 1000 * 60, (item[1] / info.latticeValue).toFixed(6)];
      });
      wsData.value[channel] = [];
      channelData.value[channel] = [];
    }
  }

  for (const index in stationType) {
    const channel: any = stationType[index];
    if (!wsData.value[channel]) continue;

    const channelDataEnd = channelData.value[channel].at(-1)?.[0] || date;

    const push = wsData.value[channel].filter((i) => i[0] > channelDataEnd);
    const seriesData = push
      .map((i) => {
        return [i[0], (i[1] / info.latticeValue).toFixed(6)];
      })
      .sort((a, b) => a[0] - b[0]);
    const seriesDataStart = seriesData[0]?.[0] || 0;
    if (seriesDataStart - channelDataEnd > 10000 / info.samplingRate) {
      channelData.value[channel].push([
        channelDataEnd + 10000 / info.samplingRate,
        '-',
      ]);
    }
    channelData.value[channel].push(...seriesData);
    //取出当前数据最后一条的时间
    const markStart = channelData.value[channel].at(-1)?.[0] || 0;

    //过滤掉被当前波形覆盖掉的图形
    channelDataOld.value[channel] = channelDataOld.value[channel].filter(
      (i) => i[0] > markStart + 1000,
    );

    series.push({
      type: 'line',
      name: channel,
      showSymbol: false,
      data: channelData.value[channel],
      xAxisIndex: index,
      yAxisIndex: index,
      lineStyle: {
        normal: {
          width: 1,
        },
        emphasis: { width: 1 },
      },
      markPoint: {
        symbol: 'pin',
        symbolSize: 30,
        itemStyle: {
          color: 'rgb(255, 70, 131)',
        },
        data: [
          {
            name: '最大值',
            type: 'max',

            label: {
              color: '#fff',
            },
          },
          {
            name: '最大值',
            type: 'min',

            label: {
              color: '#fff',
            },
          },
        ],
      },
      markArea: {
        itemStyle: {
          color: color[index],
          opacity: 1,
        },
        data: [
          [
            {
              xAxis: markStart,
            },
            {
              xAxis: markStart + 1000,
            },
          ],
        ],
      },
    });
    seriesOld.push({
      type: 'line',
      name: channel,
      showSymbol: false,
      data: channelDataOld.value[channel],
      xAxisIndex: index,
      yAxisIndex: index,
      lineStyle: { opacity: 0.33 },
    });
  }

  chart.setOption({
    title: {
      text: `设备标识：${info.code} | 采样率：${info.samplingRate} | 烈度：${info.intensity} | 数据延迟：${(channelData.value['EIZ'].at(-1)?.[0] - now) / 1000}秒`,
      show: props.showTitle,
    },
    ...xAxis,
    series: [...seriesOld, ...series],
  });
};
</script>

<style lang="scss" scoped>
#wave_form {
  #graphics {
    width: 100%;
    height: 100%;
  }
}
</style>
